﻿open System.Linq
open System.Collections.Generic

let sim_pearson (prefs:Dictionary<string, Dictionary<string, double>>) (p1:string) (p2:string) =
    
    let si = new Dictionary<string, int>()
    
    for item in prefs.[p1].Keys do
        if prefs.[p2].Keys.Contains(item) 
            then si.[item] <- 1
    
    if si.Count = 0 then 0
        else
        let sum1 = Seq.sum( seq {for it in si.Keys do prefs.[p1].[it]})
        let sum2 = Seq.sum( seq {for it in si.Keys do prefs.[p2].[it]})

        let sum1Sq = Seq.sum( seq{for it in si.Keys do pown(prefs.[p1].[it],2) })
        let sum2Sq = Seq.sum( seq{for it in si.Keys do pown(prefs.[p2].[it],2) })
        
        let pSum = Seq.sum( seq{for it in si.Keys do prefs.[p1].[it]*prefs.[p2].[it]})
        
        let n = si.Count
        
        let num=pSum-(sum1*sum2/n)
        
        let den = sqrt((sum1Sq-pow(sum1,2)/n)*(sum2Sq-pow(sum2,2)/n))
        
        if den==0 then 0
        
        num/den